package com.yunhe.authority.controller.office;

import com.yunhe.authority.domain.office.Office;
import com.yunhe.authority.model.housing.*;
import com.yunhe.authority.service.office.OfficeService;
import com.yunhe.common.annotation.OperationRecord;
import com.yunhe.common.constant.SystemConsts;
import com.yunhe.common.exception.ArgumentErrorException;
import com.yunhe.common.exception.ModelNotFoundException;
import com.yunhe.common.exception.ObjectNotFoundException;
import com.yunhe.common.exception.UniqueConstraintsException;
import com.yunhe.common.model.ResultObject;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
import java.util.Optional;

/**
 * 厂房controller
 * @author zhengbo
 * @date 2020/11/4 16:25
 */
@Api(value = "Office", description = "厂房", tags = {"Model_Office"})
@RequestMapping("/office")
@RestController
public class OfficeController {

    @Autowired
    private OfficeService officeService;


    /**
     * 新增厂房
     * @param office 厂房
     */
    @ApiOperation("新增厂房")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "companyId", value = "企业ID", required = false, dataType = "Long", paramType = "query"),
            @ApiImplicitParam(name = "realStationId", value = "真实园区ID", required = true, dataType = "Long", paramType = "query")
    })
    @RequestMapping(value = "/insertOffice" ,method = RequestMethod.POST)
    @OperationRecord(menu = "厂房", actionType = SystemConsts.ACTION.ADD)
    public ResponseEntity<ResultObject<Office>> insertOffice(@RequestBody Office office)
            throws ObjectNotFoundException, UniqueConstraintsException {
        Long realStationId = office.getRealStationId();
        Long companyId = office.getCompanyId();
        Office newOffice = officeService.createOffice(realStationId,companyId, office);
        return new ResponseEntity<>(new ResultObject<>(newOffice), HttpStatus.OK);
    }

    /**
     * 更新厂房（更新全部字段）
     * @param office    厂房
     */
    @ApiOperation("更新全部字段")
    /*@ApiImplicitParams({
            @ApiImplicitParam(name = "officeId", value = "厂房ID", required = true, dataType = "Long", paramType = "path")
    })*/
    @RequestMapping(value = "/updateOffice", method = RequestMethod.PUT)
    @OperationRecord(menu = "厂房", actionType = SystemConsts.ACTION.EDIT)
    public ResponseEntity<ResultObject> updateOffice(@RequestBody Office office) throws UniqueConstraintsException {
        //office.setId(officeId);
        Office newOffice = officeService.updateOffice(office);
        return new ResponseEntity<>(new ResultObject<>(newOffice), HttpStatus.OK);
    }

    /**
     * 更新厂房（更新指定字段）
     * @param officeId
     * @param buildingNumber
     * @param officeName
     * @param officeTitle
     * @param officeArea
     * @return
     * @throws ArgumentErrorException
     * @throws UniqueConstraintsException
     * @throws ObjectNotFoundException
     */
    @ApiOperation("更新指定字段")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "officeId", value = "厂房ID", required = true, dataType = "Long", paramType = "path"),
            @ApiImplicitParam(name = "buildingNumber", value = "楼栋号", dataType = "Long", paramType = "query"),
            @ApiImplicitParam(name = "officeName", value = "厂房编号", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "officeTitle", value = "厂房名称", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "officeArea", value = "厂房面积", dataType = "Double", paramType = "query")
    })
    @RequestMapping(value = "/{officeId}", method = RequestMethod.PATCH)
    @OperationRecord(menu = "厂房", actionType = SystemConsts.ACTION.EDIT)
    public ResponseEntity<ResultObject> patch(@PathVariable("officeId") Long officeId,
                                              @RequestParam("buildingNumber") Optional<Long> buildingNumber,
                                              @RequestParam("officeName") Optional<String> officeName,
                                              @RequestParam("officeTitle") Optional<String> officeTitle,
                                              @RequestParam("officeArea") Optional<Double> officeArea)
            throws ObjectNotFoundException {
        Office newOffice = officeService.updateSpecifyAttributes(officeId, buildingNumber.orElse(null),
                officeName.orElse(null), officeTitle.orElse(null), officeArea.orElse(null));
        return new ResponseEntity<>(new ResultObject<>(newOffice), HttpStatus.OK);
    }

    @ApiOperation("根据厂房id查询厂房信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "officeId", value = "厂房ID", required = true, dataType = "long", paramType = "path")
    })
    @RequestMapping(value = "/getOfficeById", method = RequestMethod.GET)
    public ResponseEntity<ResultObject<Office>> getOfficeById(@RequestParam("id") Long id) {
        Office office = officeService.findById(id);
        return new ResponseEntity<>(new ResultObject<>(office), HttpStatus.OK);
    }

    @ApiOperation("根据企业id查询厂房信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "companyId", value = "企业ID", required = true, dataType = "long", paramType = "path")
    })
    @RequestMapping(value = "/{companyId}", method = RequestMethod.GET)
    public ResponseEntity<ResultObject> getByCompanyId(@PathVariable("companyId") Long companyId)
            throws ObjectNotFoundException {
        Iterable<Office> offices = officeService.findByCompanyId(companyId);
        return new ResponseEntity<>(new ResultObject<>(offices), HttpStatus.OK);
    }

    @ApiOperation("删除厂房信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "officeId", value = "厂房ID", required = true, dataType = "long", paramType = "path")
    })
    @RequestMapping(value = "/{officeId}", method = RequestMethod.DELETE)
    @OperationRecord(menu = "厂房", actionType = SystemConsts.ACTION.DELETE)
    public ResponseEntity<ResultObject> delete(@PathVariable("officeId") Long officeId) throws ArgumentErrorException {
        officeService.deleteById(officeId);
        return new ResponseEntity<>(new ResultObject<>(), HttpStatus.OK);
    }

    @ApiOperation("根据真实电站ID查询厂房列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "realStationId", value = "真实电站ID", required = true, dataType = "long", paramType = "path")
    })
    @RequestMapping(value = "/searchByRealStationId/{realStationId}", method = RequestMethod.GET)
    public ResponseEntity<ResultObject> searchByRealStationId(@PathVariable("realStationId") Long realStationId) {
        Iterable<Office> offices = officeService.findOfficesByRealStationId(realStationId);
        return new ResponseEntity<>(new ResultObject<>(offices), HttpStatus.OK);
    }

    @ApiOperation("根据真实电站ID和厂房名称查询厂房")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "realStationId", value = "真实电站ID", required = true, dataType = "long", paramType = "path"),
            @ApiImplicitParam(name = "officeName", value = "厂房名称", required = true, dataType = "String", paramType = "query")
    })
    @RequestMapping(value = "/findByStationIdAndOfficeName/{realStationId}", method = RequestMethod.GET)
    public ResponseEntity<ResultObject> findByStationIdAndOfficeName(@PathVariable("realStationId") Long realStationId,
                                                                     @RequestParam(value = "officeName") String officeName) {
        Office office = officeService.findByStationIdAndOfficeName(realStationId, officeName);
        return new ResponseEntity<>(new ResultObject<>(office), HttpStatus.OK);
    }

    @ApiOperation("根据园区D查询厂房")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "realStationId", value = "园区ID", required = true, dataType = "long", paramType = "path"),
            @ApiImplicitParam(name = "officeName", value = "厂房名称", required = true, dataType = "String", paramType = "query")
    })
    @RequestMapping(value = "/findByStationIdAndOfficeTitle/{stationId}", method = RequestMethod.GET)
    public ResponseEntity<ResultObject> findByStationIdAndOfficeTitle(@PathVariable("stationId") Long stationId,
                                                                      @RequestParam(value = "officeTitle") String officeTitle) {
        Office office = officeService.findByStationIdAndOfficeTitle(stationId, officeTitle);
        return new ResponseEntity<>(new ResultObject<>(office), HttpStatus.OK);
    }

    @ApiOperation("设置厂房状态")
    @RequestMapping(value = "/setOfficeBooked", method = RequestMethod.POST)
    public ResponseEntity<ResultObject> setOfficeBooked(@RequestParam(value = "intentionId", required = true) Long intentionId,
                                                        @RequestParam(value = "chosenOffice", required = true) Long chosenOffice,
                                                        @RequestParam(value = "companyName", required = true) String companyName,
                                                        @RequestParam(value = "stauts", required = true) String stauts) throws ArgumentErrorException, ModelNotFoundException {
        String message = officeService.setOfficeBooked(intentionId, chosenOffice, companyName, stauts);
        return new ResponseEntity<>(new ResultObject<>(message), HttpStatus.OK);
    }

    /**
     * @Description 根据筛选条件搜索厂房
     * @Param FilterCondition filterCondition
     * @Return List<Office>
     * @Date 2021/6/24 14:03
     */
    @ApiOperation("根据筛选条件搜索厂房（房源）信息")
    @RequestMapping(value = "/getOfficeByCondition", method = RequestMethod.POST)
    public ResponseEntity<ResultObject> getOfficeByCondition(@RequestBody FilterCondition filterCondition){
        return new ResponseEntity<>(new ResultObject<>(officeService.getOfficeByCondition(filterCondition)), HttpStatus.OK);
    }

    @ApiOperation("房源面积统计")
    @RequestMapping(value = "/officeAreaStatistics", method = RequestMethod.POST)
    public ResponseEntity<ResultObject> officeAreaStatistics(@RequestBody OfficeStatisticsCondition officeStatisticsCondition){
        OfficeAreaStatistics officeAreaStatistics = officeService.officeAreaStatistics(officeStatisticsCondition);
        return new ResponseEntity<>(new ResultObject(officeAreaStatistics), HttpStatus.OK);
    }

    @ApiOperation("通过真实园区查询厂房信息")
    @RequestMapping(value = "/getOfficeByRealStationId", method = RequestMethod.GET)
    public ResultObject<List<OfficeVo>> getOfficeByRealStationId(@ModelAttribute OfficeQueryCondition officeQueryCondition){
        List<OfficeVo> officeVos = officeService.getOfficeByRealStationId(officeQueryCondition);
        return new ResultObject(officeVos);
    }

    @ApiOperation("根据真实园区ID查询空置厂房")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "realStationId", value = "真实园区ID", required = true, dataType = "long", paramType = "path")
    })
    @RequestMapping(value = "/searchVacantOfficesByRealStationId/{realStationId}", method = RequestMethod.GET)
    public ResponseEntity<ResultObject> searchVacantOfficesByRealStationId(@PathVariable(value = "realStationId",required = true) Long realStationId) {
        Iterable<Office> offices = officeService.searchVacantOfficesByRealStationId(realStationId);
        return new ResponseEntity<>(new ResultObject<>(offices), HttpStatus.OK);
    }

    @ApiOperation("厂房导入模板下载")
    @GetMapping("/downOfficeUploadTemplate")
    public ResponseEntity<ResultObject> downOfficeUploadTemplate(HttpServletResponse httpServletResponse) throws ArgumentErrorException, IOException, InvalidFormatException {
        officeService.downOfficeUploadTemplate(null,httpServletResponse);
        return null;
    }

    @ApiOperation("厂房信息批量导入")
    @PostMapping("/importOffice")
    public ResponseEntity<ResultObject> importOffice(@RequestBody MultipartFile file) throws IOException, ArgumentErrorException, InterruptedException {
        officeService.importOffice(file);
        return new ResponseEntity<>(new ResultObject<>(), HttpStatus.OK);
    }

}
